home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <a.out.h>
-
- #define POOLSIZ 100000
- #define MY_SYMTABSIZ 10000
- #define SYMTABSIZ 10000
-
- struct Nlist {
- char *N_name;
- int N_type;
- int N_value;
- };
-
- char pool[POOLSIZ+128];
- char *pp = pool;
-
- struct bhdr my_header;
- struct Nlist my_Symtab[MY_SYMTABSIZ];
- int my_Sx;
-
- struct bhdr header;
- char *text, *data, *bss;
- char *rtext, *rdata, *rbss;
- struct Nlist Symtab[SYMTABSIZ];
- int Sx;
- struct reloc rinfo;
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- if (argc < 5) {
- fprintf(stderr, "Arg count.\n");
- exit(1);
- }
- get_myself(argv[1]);
- rtext = (char *)atoi(argv[2]);
- fasload(argv[3], argv[4]);
- }
-
- get_myself(filename)
- char *filename;
- {
- struct sym sym;
- int i;
- FILE *fp;
- extern char *malloc();
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- fprintf(stderr, "Can't open %s.\n", filename);
- exit(1);
- }
- fread(&my_header, sizeof(struct bhdr), 1, fp);
- if (my_header.fmagic != FMAGIC && my_header.fmagic != NMAGIC) {
- fprintf(stderr, "Illegal magic number: 0%o.\n", my_header.fmagic);
- exit(1);
- }
- fseek(fp, my_header.tsize+my_header.dsize, 1);
- for (my_Sx=0, i=0; i<my_header.ssize-sizeof(struct sym); my_Sx++) {
- if (my_Sx >= MY_SYMTABSIZ) {
- fprintf(stderr, "Too many symbols in %s.\n", filename);
- exit(1);
- }
- if (pp >= &pool[POOLSIZ]) {
- fprintf(stderr, "String table overflow.\n");
- exit(1);
- }
- fread(&sym, 1, sizeof(struct sym), fp);
- i += sizeof(struct sym);
- my_Symtab[my_Sx].N_name = pp;
- my_Symtab[my_Sx].N_type = sym.stype;
- my_Symtab[my_Sx].N_value = sym.svalue;
- while ((*pp = getc(fp)) != '\0') {
- pp++;
- i++;
- }
- pp++;
- i++;
- }
- fclose(fp);
- }
-
- fasload(filename, outputfilename)
- char *filename, *outputfilename;
- {
- struct sym sym;
- int i, n;
- char name[100], *p;
- int type, value;
- int msx;
- FILE *fp;
- extern char *malloc();
-
- fp = fopen(filename, "r");
- if (fp == NULL) {
- fprintf(stderr, "Can't open %s.\n", filename);
- exit(1);
- }
- fread(&header, sizeof(struct bhdr), 1, fp);
- if (header.fmagic != FMAGIC) {
- fprintf(stderr, "Illegal magic number: 0%o.\n", header.fmagic);
- exit(1);
- }
- text = malloc(header.tsize+header.dsize);
- data = text + header.tsize;
- bss = data + header.dsize;
- rdata = rtext + header.tsize;
- rbss = rdata + header.dsize;
- fread(text, 1, header.tsize+header.dsize, fp);
- for (Sx=0, i=0; i<header.ssize-sizeof(struct sym); Sx++) {
- if (Sx >= SYMTABSIZ) {
- fprintf(stderr, "Too many symbols in %s.\n", filename);
- exit(1);
- }
- fread(&sym, 1, sizeof(struct sym), fp);
- i += sizeof(struct sym);
- Symtab[Sx].N_type = type = sym.stype;
- Symtab[Sx].N_value = value = sym.svalue;
- p = name;
- while ((*p++ = getc(fp)) != '\0')
- i++;
- i++;
- if ((type & N_EXT) == 0 || (type & N_TYPE) != N_UNDF)
- continue;
- for (msx = 0; msx < my_Sx; msx++) {
- if ((my_Symtab[msx].N_type & N_EXT) == 0)
- continue;
- if (strcmp(my_Symtab[msx].N_name, name) == 0) {
- Symtab[Sx].N_value = my_Symtab[msx].N_value;
- goto CONTINUE;
- }
- }
- /*
- if (value == 0)
- */
- fprintf(stderr, "Undefined symbol: %s.\n", name);
- /*
- Symtab[Sx].N_value = (int)(rtext + header.bsize);
- header.bsize += value;
- */
- CONTINUE:
- ;
- }
- fseek(fp, sizeof(struct bhdr)+header.tsize+header.dsize+header.ssize, 0);
- for (i = 0, n = header.rtsize / sizeof(struct reloc);
- i < n; i++) {
- fread(&rinfo, sizeof(struct reloc), 1, fp);
- relocate(text);
- }
- for (i = 0, n = header.rdsize / sizeof(struct reloc);
- i < n; i++) {
- fread(&rinfo, sizeof(struct reloc), 1, fp);
- relocate(data);
- }
- fclose(fp);
- fp = fopen(outputfilename, "w");
- if (fp == NULL) {
- fprintf(stderr, "Can't open %s.\n", outputfilename);
- exit(1);
- }
- fwrite(&header, sizeof(struct bhdr), 1, fp);
- fwrite(text, 1, header.tsize+header.dsize, fp);
- fclose(fp);
- }
-
- relocate(where)
- char *where;
- {
- int value;
-
- where += rinfo.rpos;
- switch (rinfo.rsegment) {
- case RTEXT:
- value = (int)rtext;
- break;
-
- case RDATA:
- value = (int)rtext;
- break;
-
- case RBSS:
- value = (int)rtext;
- break;
-
- case REXT:
- value = Symtab[rinfo.rsymbol].N_value;
- break;
- }
- switch (rinfo.rsize) {
- case RBYTE:
- *(char *)where += value;
- break;
-
- case RWORD:
- *(short *)where += value;
- break;
-
- case RLONG:
- *(int *)where += value;
- break;
- }
- }
-